﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "IfcGeometryConvertContext.h"
#include <cstdint>
#include <string>
#include <vector>
#include "OwnerPtr.h"
#include "WeakPtr.h"
#include "GbmpQuickCast.h"

namespace gcmp
{   
    class IIfcEntity;
    class IIfcParameterConverter;
    class IIfcGeometryConverter;
    class IIfcEntityIterator;


    /// \brief IFC数据模型，一个模型对应一个IFC文件
    class GCMP_IFC_INTERFACE_EXPORT IIfcBuildingModel
    {
        DEFINE_CAST_BASE(IIfcBuildingModel)
    public:
        /// \brief IFC版本
        enum class IfcSchemaVersion : int32_t
        {            
            IFC4    = 6,  
            IFC4X3  = 7,
            CUSTOM = 100
        };

        /// \brief 对标准文件头中可自定义的参数的简单封装，参见ISO-10303-21标准
        struct IfcStandardHeader
        {
            /// \brief FILEDESCRIPTION (Description,ImplementationLevel(不需要外部设置))
            std::wstring    Description;            ///<文件描述
            /// \brief FILENAME (FileName, TimeStamp(不需要外部设置), Author, Organization, PreprocessorVersion, OriginatingSystem, Rights)
            std::wstring    FileName;               ///<文件名称
            std::wstring    Author;                 ///<作者
            std::wstring    Organization;           ///<组织
            std::wstring    PreprocessorVersion;    ///<处理器和版本
            std::wstring    OriginatingSystem;      ///<数据来源的系统
            std::wstring    Authorization;          ///<授权
        };
    public:
        virtual ~IIfcBuildingModel() {}        
        
        /// \brief 获取IFC版本
        /// \return IFC版本枚举        
        virtual IfcSchemaVersion GetSchemaVersion() const = 0;
                
        /// \brief 设置自定义的文件头
        /// \param wszHeader 文件头内容
        ///文件头内容必须符合ISO-10303-21标准  
        ///注意FILE_SCHEMA中填的内容应与GetSchemaVersion的值相对应，否则使用者可能无法正确解析
        ///示例如下：
        ///HEADER;
        ///FILE_DESCRIPTION($, '2;1');
        ///FILE_NAME('CustomFileName', '2021-06-03T06:12:27+00:00', ('Author:huangxj-a'), ('Glodon'), 'Glodon GBMPApp 1.0', 'Glodon GBMP IfcExporter alpha 0.1', $);
        ///FILE_SCHEMA(('IFC4'));
        ///ENDSEC;
        GCMP_DEPRECATED_API(2023/11/1) virtual void SetCustomHeader(const std::wstring& wszHeader) = 0;

        /// \brief 根据传入的可设置参数生成标准文件头
        /// \param stdHeader，标准文件头参数结构体         
        virtual void SetStandardHeader(const IfcStandardHeader& stdHeader) = 0;
        
        /// \brief 获取当前BuildingModel的标准文件头
        /// \param 标准文件头参数结构体   
        virtual IfcStandardHeader GetStandardHeader() const = 0;

        /// \brief 创建IFC普通实体类对象。
        /// \param upperClassName 要创建的IFC对象的类名
        /// \return 返回IFC普通实体对象指针
        virtual gcmp::WeakPtr<gcmp::IIfcEntity> CreateEntity(const std::wstring& className) = 0;
        
        /// \brief 删除IfcEntity
        /// \param iEntityId EntityId
        ///根据EntityId删除对应的IfcEntity对象
        virtual void RemoveEntity(int iEntityId) = 0;        

        /// \brief 获取当前所有IfcEntity对象中EntityId的最大值
        /// \return EntityId
        ///用于计算需要给新对象设置的EntityId
        GCMP_DEPRECATED_API(2023 / 11 / 1) virtual int GetMaxUsedEntityId() const = 0;

        /// \brief 将当前Model中的所有数据写入文件
        /// \param wszFilePath 文件路径
        /// \return 写入是否成功
        ///调用该方法前需要保证所有数据都设置完成
        virtual bool Save(const std::wstring& wszFilePath) = 0;

        /// \brief 创建一个IFC的buildingModel
        /// \return 返回IFCBuildingModel指针
        static OwnerPtr<IIfcBuildingModel> Create(IfcSchemaVersion version);

        /// \brief 通过输入文件的完整路径（.exp）创建buildingModel
        /// \param schemaFilePath exp类定义文件
        /// \return 返回IFCBuildingModel指针
        static OwnerPtr<IIfcBuildingModel> Create(const std::wstring& schemaFilePath);

        /// \brief 通过输入文件的完整路径（.ifc）创建buildingModel
        /// \param filePath ifc模型文件
        /// \return 返回IFCBuildingModel指针
        static OwnerPtr<IIfcBuildingModel> Load(const std::wstring& filePath);

        /// \brief 获取参数转换器
        ///
        /// 参数转换器提供转换ifc参数相关接口
        /// \return 参数转换器指针
        virtual IIfcParameterConverter* GetParameterConverter() = 0;

        /// \brief 获取几何转换器
        /// \return 几何转换器指针
        ///几何转换器提供转换ifc形体相关接口
        virtual IIfcGeometryConverter* GetGeometryConverter() = 0;

        /// \brief 获取entity的指针
        /// \param entityId entity对象在BuildingModel中的id
        /// \return 返回entity的指针
        virtual const IIfcEntity* GetEntity(int entityId) const = 0;

        /// \brief 获取指定类的entity指针
        /// \param upperClassName, IFC类名
        /// \return 返回一组entity的指针
        virtual std::vector<OwnerPtr<IIfcEntity>> GetAllEntities(const std::string& className) const = 0;

        /// \brief 创建遍历当前BuildingModel中IfcEntity的迭代器
        /// \param entity迭代器指针   
        virtual OwnerPtr<IIfcEntityIterator> NewIterator() = 0;
    };
}

